#include <REGX52.H>

sbit I2C_SCL = P2^1;
sbit I2C_SDA = P2^0;

/**
  * @brief  I2C开始
  * @param  无
  * @retval 无
  */
void I2C_start(void)
{
    I2C_SDA = 1;  // 先将SDA置1，因为上一个“拼图”结束SDA可能是0 or 1
    I2C_SCL = 1;
    I2C_SDA = 0;
    I2C_SCL = 0;
}

/**
  * @brief  I2C停止
  * @param  无
  * @retval 无
  */
void I2C_stop(void)
{
    I2C_SDA = 0;  // 确保低电平后拉高
    I2C_SCL = 1;
    I2C_SDA = 1;
}

/**
  * @brief  I2C发送一个字节
  * @param  byte 要发送的字节
  * @retval 无
  */
void I2C_sendbyte(unsigned char byte)
{
    unsigned char i;
    for (i = 0; i < 8; i++)
    {
        I2C_SDA = byte & (0x80 >> i);  // e.g. i = 0时，取最高位赋值
        I2C_SCL = 1;
        // 根据手册，除了写周期5ms，其他来得及读数据
        I2C_SCL = 0;
    }
}

/**
  * @brief  I2C接收一个字节
  * @param  无
  * @retval 接收到的一个字节数据
  */
unsigned char I2C_receivebyte(void)
{
    unsigned char i, byte = 0x00;
    I2C_SDA = 1;  // 释放总线
    for (i = 0; i < 8; i++)
    {
        I2C_SCL = 1;
        // 若从机有控制权，I2C_SDA 1为接收0不接收
        // 若接收，则byte对应的第(i + 1)位置1
        if (I2C_SDA)
        {
            byte |= (0x80 >> i);
        }
        I2C_SCL = 0;
    }
    return byte;
}

/**
  * @brief  I2C发送应答
  * @param  ackBit 应答位，0为应答，1为非应答
  * @retval 无
  */
void I2C_sendack(bit ackBit)  // C51特有数据类型bit无符号1位
{
    I2C_SDA = ackBit;
    I2C_SCL = 1;
    I2C_SCL = 0;
}

/**
  * @brief  I2C接收应答位
  * @param  无
  * @retval 接收到的应答位，0为应答，1为非应答
  */
unsigned char I2C_receiveack(void)
{
    unsigned char ackBit; 
    I2C_SDA = 1;  // 释放SDA
    I2C_SCL = 1;
    ackBit = I2C_SDA;
    I2C_SCL = 0;
    return ackBit;  // 返回值是0有应答，1无应答
}